"""Flask middleware definitions. This is also where template filters are defined.

To be imported by the application.current_app() factory.
"""

from datetime import datetime
from logging import getLogger

from flask import current_app, render_template, request
from flask_wtf.csrf import generate_csrf
from markupsafe import Markup

LOG = getLogger(__name__)


# Setup default error templates.
# @current_app.errorhandler(400)
# @current_app.errorhandler(403)
# @current_app.errorhandler(404)
# @current_app.errorhandler(500)
# def error_handler(e):
#     code = getattr(e, 'code', 500)  # If 500, e == the exception.
#     if code == 500:
#         # Send email to all ADMINS.
#         exception_name = e.__class__.__name__
#         view_module = request.endpoint
#         LOG.error('{} exception in {}'.format(exception_name, view_module))
#     return str(code)
    # return render_template('{}.html'.format(code)), code


# Template filters.
@current_app.template_filter()
def whitelist(value):
    """Whitelist specific HTML tags and strings.

    Positional arguments:
    value -- the string to perform the operation on.

    Returns:
    Markup() instance, indicating the string is safe.
    """
    translations = {
        '&amp;quot;': '&quot;',
        '&amp;#39;': '&#39;',
        '&amp;lsquo;': '&lsquo;',
        '&amp;nbsp;': '&nbsp;',
        '&lt;br&gt;': '<br>',
    }
    escaped = str(Markup.escape(value))  # Escapes everything.
    for k, v in translations.items():
        escaped = escaped.replace(k, v)  # Un-escape specific elements using str.replace.
    return Markup(escaped)  # Return as 'safe'.


@current_app.template_filter()
def sum_key(value, key):
    """Sums up the numbers in a 'column' in a list of dictionaries or objects.

    Positional arguments:
    value -- list of dictionaries or objects to iterate through.

    Returns:
    Sum of the values.
    """
    values = [r.get(key, 0) if hasattr(r, 'get') else getattr(r, key, 0) for r in value]
    return sum(values)


@current_app.template_filter()
def max_key(value, key):
    """Returns the maximum value in a 'column' in a list of dictionaries or objects.

    Positional arguments:
    value -- list of dictionaries or objects to iterate through.

    Returns:
    Sum of the values.
    """
    values = [r.get(key, 0) if hasattr(r, 'get') else getattr(r, key, 0) for r in value]
    return max(values)


@current_app.template_filter()
def average_key(value, key):
    """Returns the average value in a 'column' in a list of dictionaries or objects.

    Positional arguments:
    value -- list of dictionaries or objects to iterate through.

    Returns:
    Sum of the values.
    """
    values = [r.get(key, 0) if hasattr(r, 'get') else getattr(r, key, 0) for r in value]
    return float(sum(values)) / (len(values) or float('nan'))


@current_app.template_filter(name='to_int')
def to_int(value):
    if value.isdigit():
        return int(value)
    else:
        return value


@current_app.template_filter(name='to_str')
def to_str(value):
    return str(value)


@current_app.template_filter(name='time_transform')
def do_time_transform(time):
    """
        time距离现在的时间间隔
        1. 如果时间间隔小于1分钟以内，那么就显示“刚刚”
        2. 如果是大于1分钟小于1小时，那么就显示“xx分钟前”
        3. 如果是大于1小时小于24小时，那么就显示“xx小时前”
        4. 如果是大于24小时小于30天以内，那么就显示“xx天前”
        5. 否则就是显示具体的时间 2017/10/20 16:15
        """
    if isinstance(time, datetime):
        now = datetime.now()
        timestamp = (now - time).total_seconds()
        if timestamp < 60:
            return "刚刚"
        elif 60 <= timestamp < 60 * 60:
            minutes = timestamp / 60
            return "%s分钟前" % int(minutes)
        elif 60 * 60 <= timestamp < 60 * 60 * 24:
            hours = timestamp / (60 * 60)
            return '%s小时前' % int(hours)
        elif 60 * 60 * 24 <= timestamp < 60 * 60 * 24 * 30:
            days = timestamp / (60 * 60 * 24)
            return "%s天前" % int(days)
        else:
            return time.strftime('%Y/%m/%d %H:%M')
    else:
        return time


@current_app.template_filter(name='split_url')
def do_split_url(url):
    surl = url.split('/')
    return '/{}/{}'.format(surl[1], surl[2])

# @current_app.after_request
# def after_request(response):
#     # 调用函数生成 csrf_token
#     csrf_token = generate_csrf()
#     # 通过 cookie 将值传给前端
#     response.set_cookie("csrf_token", csrf_token)
#     return response


@current_app.context_processor
def default_uuid_context():
    return dict(default_pk="00000000-0000-0000-0000-000000000000")


# @current_app.errorhandler(404)
# def page_not_found(e):
#     return render_template('404.html'), 404
#
#
# @current_app.errorhandler(500)
# def page_not_found(e):
#     current_app.logger.error(e)
#     return render_template('500.html'), 500
